/*

This file is part of Rooms3D.

Copyright (C) 2008 Pixecur Technologies Incorporated (Esotera).
Visit Esotera at http://www.esoteras3.com
 
Rooms3D is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
 
Rooms3D is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with Rooms3D; see the file COPYING.  If not, write to 
Pixecur Technologies, 213-31 Peet Street, St. John's, NL, A1B 3W8. 
 
Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
 
*/

package com.datasentinel.rooms.file.sh3d;

import javax.media.j3d.BranchGroup;
import javax.media.j3d.Shape3D;
import javax.vecmath.Vector3f;

import com.datasentinel.rooms.j3d.util.SceneGraphTraversalSupport;
import com.datasentinel.rooms.ui.sh3d.CustomFurnitureSupport;
import com.datasentinel.rooms.ui.sh3d.CustomFurnitureSupportException;
import com.datasentinel.util.AbstractTreeTraversalCallback;
import com.datasentinel.util.TreeTraversal;
import com.datasentinel.util.TreeTraversalSupport;
import com.eteks.sweethome3d.swing.ModelManager;
import com.eteks.sweethome3d.tools.ResourceURLContent;
import com.eteks.sweethome3d.tools.URLContent;

/**
 * @author rickp
 * 
 */
public class HaiVanPassPictureFrameFurnitureSupport implements
		CustomFurnitureSupport
{
	private static HaiVanPassPictureFrameFurnitureSupport instance;
	private URLContent content;
	private Vector3f modelSize;

	public static HaiVanPassPictureFrameFurnitureSupport getInstance()
	{
		if (instance == null)
			instance = new HaiVanPassPictureFrameFurnitureSupport();
		return instance;
	}
	
	protected HaiVanPassPictureFrameFurnitureSupport()
	{
		this(new ResourceURLContent(HaiVanPassPictureFrameFurnitureSupport.class, "HaiVanPassFrame.obj"));
	}
	
	protected HaiVanPassPictureFrameFurnitureSupport(ResourceURLContent resource)
	{
		try
		{
			content = resource;
			BranchGroup model = ModelManager.getInstance().getModel(content);
			modelSize = ModelManager.getInstance().getSize(model);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
	
	@Override
	public Vector3f getModelSize()
	{
		return modelSize;
	}

	@Override
	public URLContent getModelContent()
	{
		return content;
	}

	protected String getShapeName()
	{
		return "photo_cube_material_haivanpass.jpg";		
	}
	
	@Override
	public Shape3D[] findShapesToTextureize(BranchGroup branchGroup)
			throws CustomFurnitureSupportException
	{
		SceneGraphTraversalSupport treeTraversalSupport = getGraphTransversalImpl();
		TreeTraversalCallbackImpl treeTraversalCallback = getTransversalImpl();
		long giveUpOnThisTime = System.currentTimeMillis() + 60000L;
		Shape3D shape3d = null;
		while (shape3d == null)
		{
			if (System.currentTimeMillis() > giveUpOnThisTime)
				throw new CustomFurnitureSupportException(
						"timed out locating shape to textureize");
			TreeTraversal.traverse(branchGroup, treeTraversalSupport,
					treeTraversalCallback);
			shape3d = treeTraversalCallback.getShape();
			if (shape3d instanceof Shape3D)
				break;
			try
			{
				Thread.sleep(50);
			}
			catch (InterruptedException ie)
			{
				throw new CustomFurnitureSupportException(
						"interrupted while locating shape to textureize");
			}
		}
		return new Shape3D[] { shape3d };
	}
	
	protected SceneGraphTraversalSupport getGraphTransversalImpl()
	{
		return new SceneGraphTraversalSupport();
	}

	protected TreeTraversalCallbackImpl getTransversalImpl()
	{
		return new TreeTraversalCallbackImpl();
	}

	protected class TreeTraversalCallbackImpl extends
			AbstractTreeTraversalCallback
	{
		protected Shape3D shape;

		protected TreeTraversalCallbackImpl()
		{
			super();
		}

		protected boolean cancel = false;

		@Override
		public void traversedLeaf(Object node)
		{
			if (node instanceof Shape3D)
			{
				Shape3D shapeTmp = (Shape3D)node;
				Object userData = shapeTmp.getUserData();
				if (getShapeName().equals(userData))
				{
					shape = shapeTmp;
					cancel = true;
				}
			}
		}

		@Override
		public boolean cancel()
		{
			return cancel;
		}

		public Shape3D getShape()
		{
			return shape;
		}
	}
}
